<?php
namespace ZL;
use Think\Controller as BaseController;

class Seek extends BaseController
{
//--------------------------设置项------------------------------------
    protected $dataCacheTime = 0;//时间缓存设置

    protected $aliasOut = false;//输出重复字段是否有别名 设置

    protected $countAlias = 'count';//输出的count字段 设置

///-------------------------设置项------------------------------------

    protected $pageCss = false;//分页样式

    protected $whereArr = array(); //查询条件数组

    protected $ret = array(); //查询数据
    
    protected $page = false;  //分页

    protected $model = array();//查询模型数组

    protected $fieldData = array();//查询字段 设置

    protected $sort = '';//排序 设置
    
    protected $linkArr = array();//配置数组
    
    protected $tablesField = array();//相关表字段
    
    protected $foreign_relation = array();//关系对应数组

    protected $sentence = array();//join语句构成数组

    protected $dataCount = 1;//总数

    protected $surplus = array();//剩余的元素

    protected $cacheName = '';//缓存的名字

    protected $first = '';//第一个元素的名称

    protected $pageSize = '';//每页数量

    /**
 * 构造函数 输入模型名 生成对象 加载配置里的linkarr数组
 * @param string $file 模型名
 */
    public function __construct() {
        parent::__construct();

        $link = C('linkArr');
        foreach ($link as $k=>$v) {
            $data = explode(',',$v);
            $this->linkArr[$k] = $data;
        }
    }

    //模型定义
    public function M($name=FALSE){
        if(!$name)
            return $this;
        if(strpos($name, ' ')){
            $nameArr = explode(' ', $name);
            $this->model[$nameArr[0]] = $nameArr[1];
        }else{
            $this->model[$name] = FALSE;
        }
        return $this;
    }
    // $[name][field]=> array();
    //查询条件
    public function where($array=FALSE){
        if(!$array)
            return $this;
        else
            $this->whereArr = $array;
        return $this;
    }
    
    public function page($page1=false,$page2=false) {
        if($page1)
            $this->page[0] = $page1;
        if($page2)
            $this->page[1] = $page2;
        return $this;
    }

    public function limit($limit=false){
        if($limit) {
            $limit = explode(',',$limit);
            $this->pageSize = $limit[0];
            if($limit[1])
                $this->pageCss = C($limit[1]);
            else
                $this->pageCss = C('PAGE_01');
        }
        return $this;
    }
    
    public function order($order=FALSE) {
        if($order)
            $this->sort = $order;
        return $this;
    }


    //数据字段设置
    public function field($type=FALSE) {
        if(!field)
            return $this;
        $this->fieldData = FALSE;
        return $this;
    }
    
    //执行方法
    public function seek(){
        $this->getFeild();
        foreach ($this->model as $k=>$v) {
            $this->cacheName .= $k.$v;
        }
        $data['data'] = $this->getAll();
        $data[$this->countAlias] = $this->dataCount;
        if($pageSize=$this->pageSize){
            return $data['data'];
        }else{
            return $data;
        }
    }


    private function setSurplus($name=false){
        if($name) {

            unset($this->surplus[$name]);
        }
        else{
            $this->surplus = $this->model;
            $first_key = $this->first;
            $alias = $this->surplus[$first_key]?$this->surplus[$first_key]:strtolower($first_key);
            $this->sentence[$first_key][5] = $alias;
            unset($this->surplus[$first_key]);
        }
    }

    private function getFeild(){
        $model = $this->model;
        $this->tablesField = S($this->cacheName.'tablesField');
        if(!$this->tablesField) {
            foreach ($model as $k => $v) {
                $this->tablesField[$k] = $this->selectField($k);
            }

            $this->dataCache('tablesField',$this->tablesField);
        }
    }

    private function getRelation(){
        $this->setSurplus();
        $this->foreign_relation = S($this->cacheName.'foreign_relation');
        if(!$this->foreign_relation) {
            foreach ($this->surplus as $k => $v) {
                $this->foreign_relation[$k] = $this->chckHas($k);
            }
            $this->dataCache('foreign_relation',$this->foreign_relation);
        }
//        myDump($this->foreign_relation);
    }

//["Zone"]=>
//  array(2) {
//    [0]=>
//    string(9) "Community"
//    [1]=>
//    string(7) "zone_id"
//  }
//  ["Building"]=>
//  array(2) {
//    [0]=>
//    string(9) "Community"
//    [1]=>
//    string(11) "building_id"
//  }


    //取得最终数据
    private function getAll(){
        reset($this->model);
        $this->first = key($this->model);
        $this->getRelation();

        $this->sentence = S($this->cacheName.'sentence');
        if(!$this->sentence) {
            $this->setSurplus();
            foreach ($this->surplus as $k => $v) {
                foreach ($this->foreign_relation as $kk => $vv) {
                    if ($k == $kk) {
                        foreach ($this->sentence as $kkk => $vvv) {
//                        myDump($this->sentence);die;
                            if ($vv[0] == $kkk) {
                                $this->sentence[] = $this->getRelationStr($vvv[5], $kk, $vv);
                                continue 2;
                            }
                        }
                    }
                }
            }
            $this->dataCache('sentence',$this->sentence);
        }
        $this->fieldStr = $this->getFeildStr();
        $all = $this->getData();
        return $all;
    }

    private function getFeildStr(){
        if($this->fieldStr){

        }else{
            $this->fieldData = S($this->cacheName.'fieldData');
            if(!$this->fieldData) {
                foreach ($this->tablesField as $k => $v) {
                    foreach ($v as $vv) {
                        $allField[$k][] = $this->chckfield($k, $vv);
                    }
                }
                $str = array();
//                myDump($this->tablesField);
//                myDump($allField);
                foreach ($allField as $k => $v) {
                    foreach ($v as $vv) {
                        $alias = $this->model[$k] ? $this->model[$k] : strtolower($k);
                        if (!$str)
                            $str = "$alias.$vv";
                        else
                            $str .= ",$alias.$vv";
                    }
                }
                $this->fieldData = $str;
                $this->dataCache('fieldData',$this->fieldData);
            }
        }
    }
    private function dataCache($name,$v){
        $dataCacheTime = $this->dataCacheTime;
        if($dataCacheTime)
            S($this->cacheName.$name,$v);
    }

    private function chckfield($name,$key){
        foreach ($this->tablesField as $k=>$v){
            if($k==$name)
                continue;
            foreach ($v as $vv){
                if($key==$vv){
                    if(!$this->aliasOut)
                        $alias = strtolower($name);
                    else
                        $alias = $this->model[$name]?$this->model[$name]:strtolower($name);
                    return "$key as $alias"._."$key";
                }
            }
        }
        return $key;
    }

    public function getData(){
        $first_key = $this->first;
        $alias = $this->model[$first_key]?$this->model[$first_key]:strtolower($first_key);
        unset($this->sentence[$this->first]);
        $join = '';
        foreach ($this->sentence as $k=>$v) {
            if($v)
                $join .= "left join $v[0] $v[5] on $v[1] ";
        }
        if($pageSize=$this->pageSize){
            $count = D($this->first)->alias($alias)->join($join)->where($this->whereArr)->count();
            $page = new \ZL\Page($count, $pageSize, $this->pageCss);
            $data['page'] = $page->show();
            $data['data'] = D($this->first)->alias($alias)->field($this->fieldData)->join($join)->where($this->whereArr)->limit($page->limit.','.$page->listRows)->order($this->sort)->select();
//            myDump($this->fieldData);
//            dd(D($this->first)->getLastSql());
        }else{
            $data = D($this->first)->alias($alias)->field($this->fieldData)->join($join)->where($this->whereArr)->page($this->page[0],$this->page[1])->order($this->sort)->select();
            $this->dataCount = D($this->first)->alias($alias)->join($join)->where($this->whereArr)->count();
        }
//        dd(D($this->first)->getLastSql());
        return $data;
    }

    public function getRelationStr($parent,$name,$array)
    {
        //上级的别名 $parent
        //本级的别名
        $alias = $this->model[$name]?$this->model[$name]:strtolower($name);
        $pk = $this->linkArr[$name][2]?$this->linkArr[$name][2]:'id';
        $data[0] = $this->linkArr[$name][1]?$this->linkArr[$name][1]:D($name)->getTableName();
        $data[1] = "$parent.$array[1]=$alias.$pk";
        $data[5] = $alias;
        return $data;
    }

    private function chckHas($name){
        $foreign_key = $this->linkArr[$name][0];
        $keyArr = $this->tablesField;
        if(!$foreign_key){
            $foreign_key = strtolower($name).'_id';
        }
        foreach ($keyArr as $k => $v) {
            foreach ($v as $vv) {
                if($vv == $foreign_key) {
                    return array($k, $foreign_key);
                }
            }
        }
    }
    
    private function selectField($model) {
        $data = D($model)->getDbFields();
        return $data;
    }


}
